package cn.iocoder.yudao.module.eval.controller.admin.major;

import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameters;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import java.util.Arrays;

import cn.iocoder.yudao.module.eval.controller.admin.major.vo.*;
import cn.iocoder.yudao.module.eval.dal.dataobject.major.MajorDO;
import cn.iocoder.yudao.module.eval.service.major.MajorService;
import org.springframework.web.multipart.MultipartFile;

import cn.hutool.core.collection.CollUtil;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.eval.enums.ErrorCodeConstants.MAJOR_IMPORT_LIST_IS_EMPTY;

@Tag(name = "管理后台 - 专业管理")
@RestController
@RequestMapping("/eval/major")
@Validated
public class MajorController {

    @Resource
    private MajorService majorService;

    @PostMapping("/create")
    @Operation(summary = "创建专业管理")
    @PreAuthorize("@ss.hasPermission('eval:major:create')")
    public CommonResult<Long> createMajor(@Valid @RequestBody MajorSaveReqVO createReqVO) {
        return success(majorService.createMajor(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新专业管理")
    @PreAuthorize("@ss.hasPermission('eval:major:update')")
    public CommonResult<Boolean> updateMajor(@Valid @RequestBody MajorSaveReqVO updateReqVO) {
        majorService.updateMajor(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除专业管理")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:major:delete')")
    public CommonResult<Boolean> deleteMajor(@RequestParam("id") Long id) {
        majorService.deleteMajor(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除专业管理")
                @PreAuthorize("@ss.hasPermission('eval:major:delete')")
    public CommonResult<Boolean> deleteMajorList(@RequestParam("ids") List<Long> ids) {
        majorService.deleteMajorListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得专业管理")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('eval:major:query')")
    public CommonResult<MajorRespVO> getMajor(@RequestParam("id") Long id) {
        MajorDO major = majorService.getMajor(id);
        MajorRespVO respVO = BeanUtils.toBean(major, MajorRespVO.class);
        // 确保字段正确映射
        respVO.setCreateTime(major.getCreateTime());
        respVO.setTrainingObjective(major.getTrainingObjective());
        respVO.setStudyPeriod(major.getStudyPeriod());
        respVO.setVocationalCompetence(major.getVocationalCompetence());
        respVO.setCorrespondingOccupation(major.getCorrespondingOccupation());
        respVO.setCurriculumContent(major.getCurriculumContent());
        respVO.setUpperLevelCode(major.getUpperLevelCode());
        respVO.setNextLevelCode(major.getNextLevelCode());
        respVO.setQualificationSkillLevel(major.getQualificationSkillLevel());
        respVO.setMajorCategoryId(major.getMajorCategoryId());
        return success(respVO);
    }

    @GetMapping("/page")
    @Operation(summary = "获得专业管理分页")
    @PreAuthorize("@ss.hasPermission('eval:major:query')")
    public CommonResult<PageResult<MajorRespVO>> getMajorPage(@Valid MajorPageReqVO pageReqVO) {
        PageResult<MajorDO> pageResult = majorService.getMajorPage(pageReqVO);
        // 自定义转换，确保字段正确映射
        PageResult<MajorRespVO> respPageResult = new PageResult<>();
        respPageResult.setTotal(pageResult.getTotal());
        List<MajorRespVO> respVOList = new ArrayList<>();
        for (MajorDO majorDO : pageResult.getList()) {
            MajorRespVO respVO = BeanUtils.toBean(majorDO, MajorRespVO.class);
            // 确保字段正确映射
            respVO.setCreateTime(majorDO.getCreateTime());
            respVO.setTrainingObjective(majorDO.getTrainingObjective());
            respVO.setStudyPeriod(majorDO.getStudyPeriod());
            respVO.setVocationalCompetence(majorDO.getVocationalCompetence());
            respVO.setCorrespondingOccupation(majorDO.getCorrespondingOccupation());
            respVO.setCurriculumContent(majorDO.getCurriculumContent());
            respVO.setUpperLevelCode(majorDO.getUpperLevelCode());
            respVO.setNextLevelCode(majorDO.getNextLevelCode());
            respVO.setQualificationSkillLevel(majorDO.getQualificationSkillLevel());
            respVO.setMajorCategoryId(majorDO.getMajorCategoryId());
            respVOList.add(respVO);
        }
        respPageResult.setList(respVOList);
        return success(respPageResult);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出专业管理 Excel")
    @PreAuthorize("@ss.hasPermission('eval:major:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportMajorExcel(@Valid MajorPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<MajorDO> list = majorService.getMajorPage(pageReqVO).getList();
        // 自定义转换，确保字段正确映射
        List<MajorRespVO> respVOList = new ArrayList<>();
        for (MajorDO majorDO : list) {
            MajorRespVO respVO = BeanUtils.toBean(majorDO, MajorRespVO.class);
            // 确保字段正确映射
            respVO.setCreateTime(majorDO.getCreateTime());
            respVO.setTrainingObjective(majorDO.getTrainingObjective());
            respVO.setStudyPeriod(majorDO.getStudyPeriod());
            respVO.setVocationalCompetence(majorDO.getVocationalCompetence());
            respVO.setCorrespondingOccupation(majorDO.getCorrespondingOccupation());
            respVO.setCurriculumContent(majorDO.getCurriculumContent());
            respVO.setUpperLevelCode(majorDO.getUpperLevelCode());
            respVO.setNextLevelCode(majorDO.getNextLevelCode());
            respVO.setQualificationSkillLevel(majorDO.getQualificationSkillLevel());
            respVO.setMajorCategoryId(majorDO.getMajorCategoryId());
            respVOList.add(respVO);
        }
        // 导出 Excel
        ExcelUtils.write(response, "专业管理.xls", "数据", MajorRespVO.class, respVOList);
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获得导入专业管理模板")
    public void importTemplate(HttpServletResponse response) throws IOException {
        // 手动创建导出 demo
        List<MajorImportByPositionExcelVO> list = Arrays.asList(
            MajorImportByPositionExcelVO.builder()
                .number("1")
                .categoryCode("大类编码示例")
                .categoryName("大类名称示例")
                .code("专业编码示例")
                .skillLevel("等级示例")
                .subCategoryName("专业名称示例")
                .trainingGoal("培养目标示例")
                .studyYear("学习年限示例")
                .occupationalAbility("职业能力示例")
                .correspondingOccupation("对应或相关职业（工种）示例")
                .vocationalQualification("职业资格(职业技能等级)示例")
                .majorTeachingContent("教学内容与要求示例")
                .upperMajorCode("对应上一级专业编码示例")
                .nextLevelCode("对应下一级专业编码示例")
                .build()
        );
        // 输出
        ExcelUtils.write(response, "专业管理导入模板.xls", "专业列表", MajorImportByPositionExcelVO.class, list);
    }

    @PostMapping("/import")
    @Operation(summary = "导入专业管理")
    @PreAuthorize("@ss.hasPermission('eval:major:import')")
    @ApiAccessLog(operateType = IMPORT)
    public CommonResult<MajorImportRespVO> importExcel(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport,
            @RequestParam(value = "multipleSheets", required = false, defaultValue = "false") Boolean multipleSheets)
            throws Exception {
        // 添加调试信息
        System.out.println("Importing Excel file: " + file.getOriginalFilename());
        System.out.println("File size: " + file.getSize());
        System.out.println("Update support: " + updateSupport);
        System.out.println("Multiple sheets support: " + multipleSheets);
        
        // 1. 读取Excel文件
        List<MajorImportByPositionExcelVO> list;
        try {
            if (multipleSheets) {
                // 使用支持多工作表的读取方法
                list = ExcelUtils.readByPositionManualMultipleSheets(file, MajorImportByPositionExcelVO.class, null);
            } else {
                // 使用基于列位置的手动读取方法
                list = ExcelUtils.readByPositionManual(file, MajorImportByPositionExcelVO.class);
            }
            
            System.out.println("Read " + (list != null ? list.size() : 0) + " records from Excel");
            
            if (CollUtil.isEmpty(list)) {
                System.out.println("Excel list is empty, throwing exception");
                throw exception(MAJOR_IMPORT_LIST_IS_EMPTY);
            }
            
            // 打印前几条记录用于调试
            for (int i = 0; i < Math.min(3, list.size()); i++) {
                MajorImportByPositionExcelVO vo = list.get(i);
                System.out.println("Record " + (i+1) + ": " + vo);
                // 打印每个字段的值，包括null检查
                System.out.println("  number: " + (vo.getNumber() != null ? "'" + vo.getNumber() + "'" : "null"));
                System.out.println("  categoryCode: " + (vo.getCategoryCode() != null ? "'" + vo.getCategoryCode() + "'" : "null"));
                System.out.println("  categoryName: " + (vo.getCategoryName() != null ? "'" + vo.getCategoryName() + "'" : "null"));
                System.out.println("  code: " + (vo.getCode() != null ? "'" + vo.getCode() + "'" : "null"));
                System.out.println("  skillLevel: " + (vo.getSkillLevel() != null ? "'" + vo.getSkillLevel() + "'" : "null"));
                System.out.println("  subCategoryName: " + (vo.getSubCategoryName() != null ? "'" + vo.getSubCategoryName() + "'" : "null"));
                System.out.println("  trainingGoal: " + (vo.getTrainingGoal() != null ? "'" + vo.getTrainingGoal() + "'" : "null"));
                System.out.println("  studyYear: " + (vo.getStudyYear() != null ? "'" + vo.getStudyYear() + "'" : "null"));
                System.out.println("  occupationalAbility: " + (vo.getOccupationalAbility() != null ? "'" + vo.getOccupationalAbility() + "'" : "null"));
                System.out.println("  correspondingOccupation: " + (vo.getCorrespondingOccupation() != null ? "'" + vo.getCorrespondingOccupation() + "'" : "null"));
                System.out.println("  vocationalQualification: " + (vo.getVocationalQualification() != null ? "'" + vo.getVocationalQualification() + "'" : "null"));
                System.out.println("  majorTeachingContent: " + (vo.getMajorTeachingContent() != null ? "'" + vo.getMajorTeachingContent() + "'" : "null"));
                System.out.println("  upperMajorCode: " + (vo.getUpperMajorCode() != null ? "'" + vo.getUpperMajorCode() + "'" : "null"));
                System.out.println("  nextLevelCode: " + (vo.getNextLevelCode() != null ? "'" + vo.getNextLevelCode() + "'" : "null"));
            }
            
            // 统计字段非空率
            int totalRecords = list.size();
            Map<String, Integer> fieldStats = new HashMap<>();
            fieldStats.put("number", 0);
            fieldStats.put("categoryCode", 0);
            fieldStats.put("categoryName", 0);
            fieldStats.put("code", 0);
            fieldStats.put("skillLevel", 0);
            fieldStats.put("subCategoryName", 0);
            fieldStats.put("trainingGoal", 0);
            fieldStats.put("studyYear", 0);
            fieldStats.put("occupationalAbility", 0);
            fieldStats.put("correspondingOccupation", 0);
            fieldStats.put("vocationalQualification", 0);
            fieldStats.put("majorTeachingContent", 0);
            fieldStats.put("upperMajorCode", 0);
            fieldStats.put("nextLevelCode", 0);
            
            for (MajorImportByPositionExcelVO vo : list) {
                if (vo.getNumber() != null && !vo.getNumber().isEmpty()) fieldStats.put("number", fieldStats.get("number") + 1);
                if (vo.getCategoryCode() != null && !vo.getCategoryCode().isEmpty()) fieldStats.put("categoryCode", fieldStats.get("categoryCode") + 1);
                if (vo.getCategoryName() != null && !vo.getCategoryName().isEmpty()) fieldStats.put("categoryName", fieldStats.get("categoryName") + 1);
                if (vo.getCode() != null && !vo.getCode().isEmpty()) fieldStats.put("code", fieldStats.get("code") + 1);
                if (vo.getSkillLevel() != null && !vo.getSkillLevel().isEmpty()) fieldStats.put("skillLevel", fieldStats.get("skillLevel") + 1);
                if (vo.getSubCategoryName() != null && !vo.getSubCategoryName().isEmpty()) fieldStats.put("subCategoryName", fieldStats.get("subCategoryName") + 1);
                if (vo.getTrainingGoal() != null && !vo.getTrainingGoal().isEmpty()) fieldStats.put("trainingGoal", fieldStats.get("trainingGoal") + 1);
                if (vo.getStudyYear() != null && !vo.getStudyYear().isEmpty()) fieldStats.put("studyYear", fieldStats.get("studyYear") + 1);
                if (vo.getOccupationalAbility() != null && !vo.getOccupationalAbility().isEmpty()) fieldStats.put("occupationalAbility", fieldStats.get("occupationalAbility") + 1);
                if (vo.getCorrespondingOccupation() != null && !vo.getCorrespondingOccupation().isEmpty()) fieldStats.put("correspondingOccupation", fieldStats.get("correspondingOccupation") + 1);
                if (vo.getVocationalQualification() != null && !vo.getVocationalQualification().isEmpty()) fieldStats.put("vocationalQualification", fieldStats.get("vocationalQualification") + 1);
                if (vo.getMajorTeachingContent() != null && !vo.getMajorTeachingContent().isEmpty()) fieldStats.put("majorTeachingContent", fieldStats.get("majorTeachingContent") + 1);
                if (vo.getUpperMajorCode() != null && !vo.getUpperMajorCode().isEmpty()) fieldStats.put("upperMajorCode", fieldStats.get("upperMajorCode") + 1);
                if (vo.getNextLevelCode() != null && !vo.getNextLevelCode().isEmpty()) fieldStats.put("nextLevelCode", fieldStats.get("nextLevelCode") + 1);
            }
            
            System.out.println("字段统计 (总记录数: " + totalRecords + "):");
            for (Map.Entry<String, Integer> entry : fieldStats.entrySet()) {
                double percentage = totalRecords > 0 ? (double) entry.getValue() / totalRecords * 100 : 0;
                System.out.printf("  %s: %d/%d (%.2f%%)\n", entry.getKey(), entry.getValue(), totalRecords, percentage);
            }
        } finally {
            // 主动设置为null，帮助GC回收
            if (file != null) {
                try {
                    file.getInputStream().close();
                } catch (Exception ignored) {}
            }
        }
        
        // 2. 转换数据格式并调用服务执行导入
        List<MajorImportExcelVO> convertedList = new ArrayList<>();
        System.out.println("开始转换数据格式，原始记录数: " + list.size());
        for (int i = 0; i < list.size(); i++) {
            MajorImportByPositionExcelVO positionVO = list.get(i);
            MajorImportExcelVO vo = new MajorImportExcelVO();
            vo.setNumber(positionVO.getNumber());
            vo.setCategoryCode(positionVO.getCategoryCode());
            vo.setCategoryName(positionVO.getCategoryName());
            vo.setCode(positionVO.getCode());
            vo.setSkillLevel(positionVO.getSkillLevel());
            vo.setSubCategoryName(positionVO.getSubCategoryName());
            vo.setTrainingGoal(positionVO.getTrainingGoal());
            vo.setStudyYear(positionVO.getStudyYear());
            vo.setOccupationalAbility(positionVO.getOccupationalAbility());
            vo.setCorrespondingOccupation(positionVO.getCorrespondingOccupation());
            vo.setVocationalQualification(positionVO.getVocationalQualification());
            vo.setMajorTeachingContent(positionVO.getMajorTeachingContent());
            vo.setUpperMajorCode(positionVO.getUpperMajorCode());
            vo.setNextLevelCode(positionVO.getNextLevelCode());
            
            // 添加调试信息
            System.out.println("转换第 " + (i+1) + " 条记录:");
            System.out.println("  原始数据: " + positionVO);
            System.out.println("  转换后数据: " + vo);
            
            convertedList.add(vo);
        }
        
        System.out.println("Calling majorService.importMajor with " + convertedList.size() + " records");
        return success(majorService.importMajor(convertedList, updateSupport));
    }

}